package znet

import (
	"bytes"
	"encoding/binary"
	"errors"
	"gitee.com/hufengjiu/go-zinx/utils"
	"gitee.com/hufengjiu/go-zinx/ziface"
	"io"
)

type DataPack struct {
}

func NewDataPack() *DataPack {
	return &DataPack{}
}

func (dp *DataPack) GetHeadLen() uint32 {
	//Len + Id 8字节
	return 8
}

// 封包
func (dp *DataPack) Pack(m ziface.IMessage) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{})
	if err := binary.Write(buf, binary.LittleEndian, m.GetDataLen()); err != nil {
		return nil, err
	}

	if err := binary.Write(buf, binary.LittleEndian, m.GetMsgId()); err != nil {
		return nil, err
	}

	if err := binary.Write(buf, binary.LittleEndian, m.GetData()); err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

// 拆包
// 从conn分两次读取
func (dp *DataPack) UnPack(data []byte) (ziface.IMessage, error) {
	// 带读取位置的buf
	buf := bytes.NewReader(data)
	m := Message{}
	if err := binary.Read(buf, binary.LittleEndian, &m.DataLen); err != nil {
		return nil, err
	}

	if err := binary.Read(buf, binary.LittleEndian, &m.Id); err != nil {
		return nil, err
	}

	if m.GetDataLen() > utils.GlobalConf.MaxPacketSize {
		return nil, errors.New("packet too big")
	}

	return &m, nil

}

// 从io.reader中读取IMessage
func (dp *DataPack) UnPackFromReader(reader io.Reader) (ziface.IMessage, error) {
	buf := make([]byte, dp.GetHeadLen())
	_, err := io.ReadFull(reader, buf)
	if err != nil {
		return nil, err
	}

	// 进行拆包, 读取头部和数据长度
	m, err := dp.UnPack(buf)
	if err != nil {
		return nil, err
	}

	// 读取数据
	dataBuf := make([]byte, m.GetDataLen())
	_, err = io.ReadFull(reader, dataBuf)
	if err != nil {
		return nil, err
	}

	m.SetData(dataBuf)

	return m, nil
}
